package com.umfwechat.h5.controller.openFund;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.umfwechat.common.code.RetCode;
import com.umfwechat.common.constant.CommonConsts;
import com.umfwechat.common.constant.ConfigConsts;
import com.umfwechat.common.constant.MsgConsts;
import com.umfwechat.common.constant.PropertyConsts;
import com.umfwechat.common.constant.ValueConsts;
import com.umfwechat.common.prop.UmfPropModel;
import com.umfwechat.util.DesUtil;
import com.umfwechat.util.HttpHelper;
import com.umfwechat.util.HttpUtil;
import com.umfwechat.util.PropertyUtil;
import com.umfwechat.util.ReqMessageUtil;
import com.umfwechat.util.RequestUtil;
import com.umfwechat.util.ResultJsonUtil;
import com.umfwechat.util.SmsCheckUtil;
import com.umfwechat.util.StringUtil;
import com.umfwechat.util.wx.DateUtil;
import com.umpay.operation.common.ReqMessage;
import com.umpay.operation.common.ResMessage;
import com.umpay.operation.model.edrawInf.EdrawInf;
import com.umpay.operation.model.merRelation.MerRelation;
import com.umpay.operation.model.merchant.Protocol;
import com.umpay.operation.model.product.MerProduct;
import com.umpay.operation.service.edrawInf.remote.EdrawInfServiceRemote;
import com.umpay.operation.service.fundPurchase.FundServiceRemote;
import com.umpay.operation.service.merRelation.MerRelationServiceRemote;
import com.umpay.operation.service.merchant.remote.IProtocolServiceRemote;
import com.umpay.operation.service.product.MerProductServiceRemote;
import com.umpay.operation.util.CommonUtils;
import com.umpay.sp.service.account.remote.EntrustEdrawServiceRemote;
import com.umpay.sp.service.saas.remote.StoreInfServiceRemote;
import com.umpay.sp.util.SequenceUtil;

/**
 * 验证、开通基金产品
 * @author css
 *
 */
@Controller
@RequestMapping("h5/openFundController")
public class openFundController {
	
	//商户产品关系接口
	@Resource
	private MerProductServiceRemote merProductServiceRemote;
	//基金申购预约商户接口
	@Resource
	private FundServiceRemote fundServiceRemote;
	//查询商户业务协议接口
	@Resource
	private IProtocolServiceRemote iProtocolServiceRemote;
	//店铺部署详情接口
	@Resource
	private StoreInfServiceRemote storeInfServiceRemote;
	//查询商户绑卡信息接口
	@Resource
	private EdrawInfServiceRemote edrawInfRemote;
	//自动提现接口
	@Resource
	private EntrustEdrawServiceRemote entrustEdrawServiceRemote;
	//商户关系
	@Resource
	private MerRelationServiceRemote merRelationServiceRemote;
	
	private static Logger logger = LoggerFactory.getLogger(openFundController.class);
	
	/**
	 *校验短信验证码、开通基金账户
	 * @param request
	 * @param reponse
	 * @return
	 * 开通基金账户流程：
	 *1.验证短信验证码
	 *2.绑定基金产品关系
	 *3.配置商户业务协议（先查询）
	 *4.入基金自动申购预约商户表（查询商户收款人信息等）
	 *5.开通基金账户（开启基金自动申购）
	 *6.关闭自动提现
	 */
	@RequestMapping(value="openFund",method={RequestMethod.POST,RequestMethod.GET},produces="text/html;charset=UTF-8")
	@ResponseBody 
	public String openFund(HttpServletRequest request, HttpServletResponse reponse, String mobileNo, String verifyCode){
 		logger.info("【验证短信验证码、开通基金产品接口】开始");
		HttpSession session = request.getSession();
		String merId = session.getAttribute(CommonConsts.MERID).toString();
		//校验参数
		if(StringUtil.isEmpty(merId)){
			logger.info("商户号为空！");
			return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433077);
		}
		if(StringUtil.isEmpty(mobileNo)){
			logger.info("获取到手机号为空！");
			return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433077);
		}
		if(StringUtil.isEmpty(verifyCode)){
			logger.info("获取短信验证码为空");
			return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433077);
		}
		try {
			//~~~~~~~~~~~~~~~~~~~~~~~~~~验证短信验证码~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			String trace=StringUtil.trim(session.getAttribute("smsVerifyTrace"));	//从session中获取流水号
			if(StringUtil.isEmpty(trace)){
				logger.info("获取到流水号为空！");
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
			}
			logger.info("【校验短信验证码】入参"+"商户号："+merId +"手机号："+mobileNo + "验证码："+ verifyCode +"流水号：" + trace);
			Map<String, String> res = SmsCheckUtil.checksms(mobileNo, trace, verifyCode);
			logger.info("【校验短信验证码】出参" + res);
			if(StringUtil.isEmpty(res.get("retCode"))){
				logger.info("校验短信验证码失败");
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433078);
			}
			if(!RetCode.SUCCESS.equals(res.get("retCode"))){
//				if("00080705".equals(res.get("retCode"))){
//					logger.info("验证码错误！");
//					return ResultJsonUtil.resultJson("00060700", MsgConsts.E00433089);
//				}
				logger.info("验证码错误");
				return ResultJsonUtil.resultJson(RetCode.REQPARAM_ERR, MsgConsts.E00433089);
			}
			//配置文件获取基金产品产品号
			String productId = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","productId.saas.Fund","");
			logger.info("配置文件中获取到的基金产品编号：" + productId); 
			String productIds[] =productId.split("&"); 
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~添加基金产品关系~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			String error ="";
			for(String pId : productIds){
				error = addMerProduct(pId, merId);
			}
			if(StringUtil.isNotEmpty(error)){
				logger.info("配置基金商户产品关系失败");
				return ResultJsonUtil.resultJson(RetCode.FAIL, "");
			} 
			//配置费率
			String prodId = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","productId.saas.FundRate","");
			logger.info("配置文件中获取到的基金产品编号：" + prodId); 
			String prodds[] =prodId.split("&"); 
			for(String pIdRate : prodds){
				logger.info(String.format("==★====★★★★★★★★★★★====★==主商户注册操作【7】：产品费率信息，产品编号：productID"+pIdRate));
			    Map<String, String> mapp = allocationRate(pIdRate,merId);
				if(!RetCode.SUCCESS.equals(mapp.get(CommonConsts.RETCODE))){
					logger.info("配置基金商户新品费率失败");
					return ResultJsonUtil.resultJson(RetCode.FAIL, "");
				}
			}
			//配置文件获取基金的业务协议编号
			String BProductId = PropertyConsts.BPRODUCTID;
			String  state =  PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties", "productId.saas.Fund.BProductIdState","");
			logger.info("配置文件中读取到基金商户业务协议编号："+ BProductId);
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~查询商户的基金商户业务协议~~~~~~~~~~~~~~~~~~~~~~~~~~
			ReqMessage reqMes = ReqMessageUtil.makeOpReq();
			reqMes.getReqMap().put("merId", merId);
			reqMes.getReqMap().put("businessProductId", BProductId);
			logger.info("【查询商户基金业务协议接口】入参：" + reqMes);
			ResMessage resMes = iProtocolServiceRemote.list(reqMes);
			logger.info("【查询商户基金业务协议接口】出参：" + resMes);
			if( !resMes.getRetCode().equals(RetCode.SUCCESS)){
				logger.info("查询商户的基金业务协议失败");
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
			}
			logger.info("查询商户的基金商户业务协议成功");
			List<Protocol> protocolList = (List<Protocol>) resMes.getResMap().get("resultList");
			//是否已经基金商户业务协议配置
			//未配置
			if((protocolList == null || protocolList.size() ==0)){
				//~~~~~~~~~~~~~~~~~~~~~~~~~~配置基金的商户业务协议~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				ReqMessage reqM = ReqMessageUtil.makeOpReq();
				//生成业务协议编号
				reqM.put("businessProtocolId",this.createMbAgreementId(merId, BProductId)); // 协议号
				logger.info("生成【商户业务协议号】成功。");
				String effTime = CommonUtils.dateFormat(new SimpleDateFormat("yyyyMMdd").format(System.currentTimeMillis()));
				// 此处增加50年
				String expireTime = CommonUtils.dateFormat(new SimpleDateFormat("yyyyMMdd").format((System.currentTimeMillis()) + 1000000000));
				reqM.put("takeEffectTime", effTime);
				reqM.put(CommonConsts.EXPIRETIME, expireTime);
				reqM.put("inUser", "saas");
				reqM.put("modUser", "saas");
				reqM.put(CommonConsts.STATE, state);
				reqM.put("registerChannelId", "Saas");
				reqM.put(CommonConsts.MERID, merId);
				reqM.put(CommonConsts.BUSINESSPRODUCTID, BProductId);
				logger.info("【配置商户的基金商户业务协议接口】入参" + reqM);
				ResMessage resM = iProtocolServiceRemote.save(reqM);
				logger.info("【配置商户的基金商户业务协议接口】出参" + resM);
				//是否成功
				if( !resM.getRetCode().equals(RetCode.SUCCESS)){
					logger.info("配置商户业务协议失败");
					return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
				}
				logger.info("配置商户的基金商户业务协议成功");
			}
			if( protocolList.size() !=0 && protocolList.get(0).getState() != 2){
				//~~~~~~~~~~~~~~~~~~~~~~~~~~配置基金的商户业务协议~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				logger.info("商户业务协议状态不可用：" + protocolList.get(0).getState());
				ReqMessage reqM = ReqMessageUtil.makeOpReq();
				//生成业务协议编号
				reqM.put("businessProtocolId",this.createMbAgreementId(merId, BProductId)); // 协议号
				logger.info("生成【商户业务协议号】成功。");
				String effTime = CommonUtils.dateFormat(new SimpleDateFormat("yyyyMMdd").format(System.currentTimeMillis()));
				// 此处增加50年
				String expireTime = CommonUtils.dateFormat(new SimpleDateFormat("yyyyMMdd").format((System.currentTimeMillis()) + 1000000000));
				reqM.put("takeEffectTime", effTime);
				reqM.put(CommonConsts.EXPIRETIME, expireTime);
				reqM.put("inUser", "saas");
				reqM.put("modUser", "saas");
				reqM.put(CommonConsts.STATE, state);
				reqM.put("registerChannelId", "Saas");
				reqM.put(CommonConsts.MERID, merId);
				reqM.put(CommonConsts.BUSINESSPRODUCTID, BProductId);
				logger.info("【配置商户的基金商户业务协议接口】入参" + reqM);
				ResMessage resM = iProtocolServiceRemote.update(reqM);
				logger.info("【配置商户的基金商户业务协议接口】出参" + resM);
				//是否成功
				if( !resM.getRetCode().equals(RetCode.SUCCESS)){
					logger.info("配置商户业务协议失败");
					return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
				}
				logger.info("【配置商户的基金商户业务协议成功】");	
			}
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~基金申购预约商户查询接口~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			ReqMessage reqMess = ReqMessageUtil.makeOpReq();
			reqMess.put(CommonConsts.MERID,  merId);
//			reqMess.put(CommonConsts.STATE,"1");//0关闭   1开启
			reqMess.put(CommonConsts.FUNDNO, PropertyConsts.FUNDNO);
			logger.info("【基金申购预约商户查询接口】入参" + reqMess);
			ResMessage resMess = fundServiceRemote.queryFundMerInfo(reqMess);
			logger.info("【基金申购预约商户查询接口】出参" + resMess);
			if(!resMess.getRetCode().equals(RetCode.SUCCESS)&&!resMess.getRetCode().equals("0")){
				logger.info("查询基金申购预约商户失败");
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
			}
//			FundMerInfo fundmerInfo = (FundMerInfo) resMess.getResMap().get("fundmerInfo");
			//商户自动申购基金是否已经入表
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~店铺部署详情信息接口，查询收款人信息~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			String payeeMobileId = "";
			com.umpay.sp.model.common.ReqMessage reqq= ReqMessageUtil.makeSpReq();
			reqq.getReqMap().put(CommonConsts.STOREID, merId);
			logger.info("店铺部署详情信息接口入参：" + reqq);
			com.umpay.sp.model.common.ResMessage ress = storeInfServiceRemote.getStoreInfByPri(reqq);
			logger.info("店铺部署详情信息接口出参：" + ress);
			if(!ress.getRetCode().equals(RetCode.SUCCESS)){	//查询失败
				logger.info("查询收款人信息失败merId："+merId);
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
			}
			com.umpay.sp.model.saas.StoreInf storeInfoo =  (com.umpay.sp.model.saas.StoreInf) ress.getResMap().get(CommonConsts.STOREINF);
			if(storeInfoo ==null ||storeInfoo.equals("")){		//无数据
				logger.info("查询收款人信息无数据merId："+merId);
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
			}
			if(StringUtil.isEmpty(storeInfoo.getPayeeInidcard())){
				logger.info("收款人身份证号为空！");
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433081);
			}
			if(StringUtil.isEmpty(storeInfoo.getPayeeName())){
				logger.info("收款人姓名为空！");
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433065);
			}
			if(StringUtil.isEmpty(storeInfoo.getPrestorePhone())){		
				logger.info("收款人预留手机号为空！使用收款人手机号申购基金！");
				 payeeMobileId = storeInfoo.getPayeeMobileId();
			}
			if(StringUtil.isNotEmpty(storeInfoo.getPrestorePhone())){
				logger.info("收款人预留手机为：" + storeInfoo.getPrestorePhone());
				 payeeMobileId = storeInfoo.getPrestorePhone();
			}
			String payeeInidcard = storeInfoo.getPayeeInidcard();  //查出的收款人身份证号是密文
			//收款人姓名加密
			String desKey = StringUtil.trim(PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties", "des.secureKey","KSagZxG3"));
			DesUtil desUtil = new DesUtil(desKey);
			String payeeName = storeInfoo.getPayeeName();	//收款人姓名
			//~~~~~~~~~~~~~~~~~~~~~~~查询商户绑定额银行卡卡号~~~~~~~~~~~~~~~~~~~~~~~~
			ReqMessage reqMe = ReqMessageUtil.makeOpReq();
			Map<String, Object> reqMap = new HashMap<String, Object>();
			reqMap.put(CommonConsts.MERID, merId);
		    reqMap.put(CommonConsts.DELAYDAYS, 1);
		    reqMap.put(CommonConsts.STATE, ValueConsts.STATE_TWO);
		    reqMe.setReqMap(reqMap);
			logger.info("查询商户绑定银行卡信息接口入参：" + reqMe);
			com.umpay.operation.common.ResMessage resMe = edrawInfRemote.queryEdrewInf(reqMe);
			logger.info("查询商户绑定银行卡信息接口出参：" + resMe);
			EdrawInf edrawInfReData =(EdrawInf) resMe.getResMap().get("edrawInf");
			String bankAccount = desUtil.enc_des(edrawInfReData.getBankAccount());
//			String bankCode = edrawInfReData.getBinBankId();//写死VBC基金开户接口要求
			//未入表（基金自动申购商户信息表）
		    if(resMess.getRetCode().equals("0") ){
				//~~~~~~~~~~~~~~~~~~~~~~~~基金申购预约商户新增接口~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				ReqMessage reqs = ReqMessageUtil.makeOpReq();
				reqs.put(CommonConsts.ID,UUID.randomUUID().toString());
				reqs.put(CommonConsts.MERID,StringUtil.trimObjectFields(merId));
				reqs.put(CommonConsts.MERUSERID,StringUtil.trim(merId));
				reqs.put(CommonConsts.SOURCECHANNEL,PropertyConsts.SOURCECHANNEL_EC030004);
				reqs.put(CommonConsts.FUNDCHANNELCODE,PropertyConsts.FUNDMERID);//基金渠道编码
				reqs.put(CommonConsts.FUNDNO,PropertyConsts.FUNDNO);//基金编号
				reqs.put(CommonConsts.FUNDNAME,PropertyConsts.FUNDNAME);//基金名称
				reqs.put(CommonConsts.BPRODUCTID,PropertyConsts.BPRODUCTID);
				reqs.put(CommonConsts.PUBPRIFLAG,ValueConsts.ZERO);//对公对私标识 默认0对公
				reqs.put(CommonConsts.STATE,ValueConsts.STATE_ONE);//01自动申购开启
				logger.info("【基金自动申购商户新增接口】入参"+ reqs);
				ResMessage resss = fundServiceRemote.insertFundMerInfo(reqs);
				logger.info("【基金自动申购商户新增接口】出参"+ resss);
				if(!resss.getRetCode().equals(RetCode.SUCCESS)){
					logger.info("基金自动申购预约商户新增接口调用失败！");
					return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
				}
				logger.info("基金自动申购预约商户信息新增接口成功!");
			}
		    //判断商户是否配置了商户产品关系
		    //~~~~~~~~~~~~~~~~~~~~~~~~~~查询商户关系~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		    ReqMessage  rq = ReqMessageUtil.makeOpReq();
			String fundMerIdSH = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.FUNDMERIDSH);
			String fundSHGXBproductId = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.FUNDSHGXBPRODUCTID);
			rq.put("merId2",merId);
			rq.put("merRelType","1");
		    rq.put("merId1",fundMerIdSH);
		    rq.put("bproductId",fundSHGXBproductId);
		    logger.info("【查询商户关系接口】入参："+ rq);
		    ResMessage rs = merRelationServiceRemote.merRelationList(rq);
		    logger.info("【查询商户关系接口】出参："+ rs);
		    if(!RetCode.SUCCESS.equals(rs.getRetCode())){
		    	logger.info("查询商户关系失败！");
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
		    }
			List<MerRelation> selectMerId2List = (List<MerRelation>) rs.getResMap().get("resultList");//查询已开通的关系商户
			//已配置商户关系
			if(null != selectMerId2List && selectMerId2List.size() > 0){
				MerRelation merRelation = selectMerId2List.get(0);
				Short stateTwo = merRelation.getState();
				String trim = StringUtil.trim(stateTwo);
				if(!"2".equals(trim)){
					if(StringUtil.isEmpty(fundSHGXBproductId)||StringUtil.isEmpty(merId)||StringUtil.isEmpty(fundMerIdSH)){
						return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016); 
					}
					ReqMessage rqm = ReqMessageUtil.makeOpReq();
					rqm.put("merId1",fundMerIdSH);//基金商户号
					rqm.put("merId2",StringUtil.trim(merId));
					rqm.put("merRelType","1");
					rqm.put("state","2");
					rqm.put("bproductId",fundSHGXBproductId);//基金商户关系产品号
					//rqm.put("modUser",StringUtil.trim(merId));
					logger.info("【修改商户关系接口】入参："+rqm);
					ResMessage rsm = merRelationServiceRemote.updateMerRelationState(rqm);
					logger.info("【修改商户关系接口】出参："+rsm);
					if(!RetCode.SUCCESS.equals(rsm.getRetCode())){
						logger.info("修改商户关系失败！");
						return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
					}
					logger.info("商户重新配置商户关系!");
				}else{
					logger.info("商户已配置商户关系!");
				}
			
			}
			//未配置商户关系
			if(selectMerId2List == null || selectMerId2List.size() == 0){
				//~~~~~~~~~~~~~~~~~~~~~~~~~~添加商户关系~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				ReqMessage rqm = ReqMessageUtil.makeOpReq();
//				String fundMerIdSH = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.FUNDMERIDSH);
				logger.info("基金商户号为：" + fundMerIdSH);
//				String fundSHGXBproductId = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.FUNDSHGXBPRODUCTID);
				logger.info("基金商户关系产品号为：" + fundSHGXBproductId);
				rqm.put("merId1",fundMerIdSH);
				rqm.put("merId2",StringUtil.trim(merId));
				rqm.put("merRelType","1");
				rqm.put("state","2");
				rqm.put("bproductId",fundSHGXBproductId);
				rqm.put("modUser",StringUtil.trim(merId));
				logger.info("【添加商户关系接口】入参："+rqm);
				ResMessage rsm = merRelationServiceRemote.addMerRelation(rqm);
				logger.info("【添加商户关系接口】出参："+rsm);
				if(!RetCode.SUCCESS.equals(rsm.getRetCode())){
					logger.info("添加商户关系失败！");
					return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
				}
				logger.info("配置商户关系成功！");
			}
			//~~~~~~~~~~~~~~~~~~~~~~~~~~开通基金账户接口~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			String url = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.OPENFUNDACCOUNTURL);
			String merUserBankCard = null ;
			merUserBankCard = desUtil.enc_des(merId);
			Map<String , Object> param = new HashMap<String, Object>();
			com.umfwechat.common.ReqMessage req = ReqMessageUtil.makeFundReq();
			param.put(CommonConsts.RPID, StringUtil.trim(req.getRpid()));
			param.put(CommonConsts.REQDATE, StringUtil.trim(req.getReqDate()));
			param.put(CommonConsts.REQTIME, StringUtil.trim(req.getReqTime()));
			param.put(CommonConsts.FUNCODE, ValueConsts.FUNCODE);
			param.put(CommonConsts.USERMERID, StringUtil.trim(merId));
			param.put(CommonConsts.MERUSERID, StringUtil.trim(merId));
			param.put(CommonConsts.MERUSERNAME,payeeName);
			param.put(CommonConsts.MERUSERIDNUMBER, payeeInidcard);
			param.put(CommonConsts.MERUSERBANKCARD,merUserBankCard);
			param.put(CommonConsts.MOBILEID,payeeMobileId);
			param.put(CommonConsts.FUNDMERID,PropertyConsts.FUNDMERID);
			param.put(CommonConsts.FUNDNO,PropertyConsts.FUNDNO);
//			param.put(CommonConsts.BANKCODE,bankCode);
			param.put(CommonConsts.BANKCODE,"VBC");//
			param.put(CommonConsts.BPRODUCTID,PropertyConsts.BPRODUCTID);
			param.put(CommonConsts.SOURCECHANNEL,PropertyConsts.SOURCECHANNEL_EC030004);
			logger.info("【基金个人申请开户接口】入参" + param);
			logger.info("请求地址" + url);
		    RequestUtil requestUtil = new RequestUtil();
			Map<String, Object> resMapp= (Map<String, Object>) requestUtil.sendRequestForPost(url, param);
		    logger.info("【基金个人申请开户接口】出参" + resMapp);
			if(!RetCode.SUCCESS.equals(resMapp.get("retCode"))){
				logger.info("基金个人申请卡户接口调用失败！");
				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
			}
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~开启基金自动申购商户的状态~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//			String stateFund = ValueConsts.STATE_ONE;//基金自动申购状态    0关闭；  1开启
//			ResMessage ressAuto = this.autoPurchaseChange(request, reponse, stateFund);
//			if(!RetCode.SUCCESS.equals(ressAuto.getRetCode())){
//				logger.info("基金自动申购状态修改失败！");
//				return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
//			}
//			logger.info("基金自动申购状态开启成功！");
			//标记成功
			logger.info("基金个人申请开户成功");
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~关闭商户自动提现功能~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//			调用公共方法
			String stateTX = "0";
			com.umfwechat.common.ResMessage resTX = this.txChange(request, reponse, stateTX ,merId);
			if( !resTX.getRetCode().equals(RetCode.SUCCESS)){
				logger.info("关闭自动提现失败！！");
				return ResultJsonUtil.resultJson(RetCode.SUCCESS, "基金开户成功！关闭自动提现失败！");
			}
			logger.info("关闭自动提现成功！");
			return ResultJsonUtil.resultJson(RetCode.SUCCESS,MsgConsts.I00433116 );
		} catch (Exception e) {
			logger.info("验证开通基金产品失败！");
			return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433016);
		}
	}
	
	/**
	 * 配置产品关系
	 * @param pId
	 * @param storeInf
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String addMerProduct(String pId, String merId){
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res = null;
		req.put("merId",merId);	//商户ID
		req.put("productId",pId);	//产品ID
		try {
		//~~~~~~~~~~~~~~~~~~~~~~通过商户ID和产品ID，查看商户产品的绑定关系~~~~~~~~~~~~~~~~~~~~~~~~
			logger.info("【查询商户产品关系】入参"+req);
			res = merProductServiceRemote.getMerProductByKey(req);
			logger.info("【查询商户产品关系】出参"+res);
		} catch (Exception e) {
			logger.error("==★====★★★★★★====★==子商户注册操作【6】：查询商户产品的绑定关系异常");
			return "【6】：查询商户产品的绑定关系失败";
		}
		if(!"0000".equals(res.getRetCode())){
			logger.info("==★====★★★★★★====★==子商户注册操作【6】：查询商户产品的绑定关系失败");
			return "【6】：查询商户产品的绑定关系失败";
		}
		MerProduct merProduct = (MerProduct) res.getResMap().get("merProduct");
		if(merProduct == null){
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~添加商户产品绑定关系~~~~~~~~~~~~~~~~~~~~~~~~~~
			//调用CRM进行创建关系
			Map<String, Object> reqMap = new HashMap<String, Object>();
			String payElement = "";// 支付元素
			String ptype = pId.substring(3, 4); // 取产品号中付款标志位
			if (ptype.equals("5") || ptype.equals("7")) { // 信用卡无磁无密支付，信用卡无磁无密预授权
				payElement = "010203"; // 设置支付要素（cvv）
			} else if (ptype.equals("6")) { // 借记卡无磁无密支付
				payElement = "01";
			} else if (ptype.equals("4")) { // U付账户支付
				payElement = "";
			} else if ("P0000001".equals(pId) || "P0000002".equals(pId)) {
				payElement = "";
			} else {
				payElement = "";
			}
			reqMap.put("rpid", req.getRpid());
			reqMap.put("funCode","QYZH");	//
			reqMap.put("merId",merId);	//商户ID
			reqMap.put("accTypeTag", "2");	//开户类型
			reqMap.put("productId", pId);	//产品ID
			reqMap.put("playelements", payElement);
			reqMap.put("RegPointTag", "40");	//开通渠道
			reqMap.put("sendSMS", "2");
			Map<String, Object> crmResult = null;
			String retCode = "";
			try {
				XStream xstream = new XStream(new DomDriver());
				// URL配置文件取
				String url = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","upay.crm.account.url", "");	//获取商户产品绑定关系URL
				//调用受理注销用户标识接口
				logger.info("获取商户产品绑定关系请求的url：" + url);
				crmResult = (Map<String, Object>) HttpHelper.getResObjPost(url, xstream, reqMap);
				retCode = (String) crmResult.get("retCode");
				if (!"0000".equals(retCode)){
					logger.info("==★====★★★★★★====★==子商户注册操作【6】：请求CRM系统失败:添加商户产品的绑定关系失败");
					return "【6】：添加商户产品的绑定关系失败";
				}
			} catch (Exception e) {
				logger.error("==★====★★★★★★====★==子商户注册操作【6】：请求CRM系统失败:添加商户产品的绑定关系异常");
				return "【6】：添加商户产品的绑定关系失败";
			}
			if(crmResult==null || crmResult.isEmpty()) {
				logger.info("==★====★★★★★★====★==子商户注册操作【6】：请求CRM系统失败:添加商户产品的绑定关系失败");
				return "【6】：添加商户产品的绑定关系失败";
			}
		}
		return null;
	}
	
	/**
	 * 创建商户业务协议号
	 * @param merId
	 * @param businessProductId
	 * @return
	 * @throws Exception
	 */
	private String createMbAgreementId(String merId, String businessProductId)
			throws Exception {
		logger.info("生成【商户业务协议号】  ------start");
		if (CommonUtils.isEmpty(merId)
				|| CommonUtils.isEmpty(businessProductId))
			return null;

		StringBuilder protocolId = new StringBuilder();
		try {
			// 商户号-业务产品-日期-4位流水
			protocolId.append(merId).append("-");
			protocolId.append(businessProductId).append("-");
			protocolId.append(DateUtil.date8(new Date())).append("-");
			protocolId.append(SequenceUtil.getSeq("merBusiAgr", 4));
			logger.info("生成商户业务协议号：" + protocolId.toString() + "------end");
			return protocolId.toString();
		} catch (Exception e) {
			logger.error("生成【商户业务协议号】  ------end。", e);
			throw new Exception("生成商户业务协议号失败！", e);
		}
	}
	/**
	 * 基金自动申购状态修改公共方法
	 * @param request
	 * @param response
	 * @param state
	 * @return
	 */
	public ResMessage autoPurchaseChange(HttpServletRequest request, HttpServletResponse response,String state){
		logger.info("【基金自动申购状态修改接口】开始");
		String merId = StringUtil.trim(request.getSession().getAttribute(CommonConsts.MERID).toString());
		ResMessage res = new ResMessage();
		if(StringUtil.isEmpty(merId)){
			logger.info("获取merId失败！");
			res.setRetCode(RetCode.FAIL);
			res.setRetMsg("获取商户号失败！");
			return res;
		}
		if(StringUtil.isEmpty(state)){
			logger.info("获取state值失败");
			res.setRetCode(RetCode.FAIL);
			res.setRetMsg("获取state失败！");
			return res;
		}
		try {
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~基金自动申购预约商户信息修改接口~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			ReqMessage req = ReqMessageUtil.makeOpReq();
			req.put(CommonConsts.MERID,merId);
			req.put(CommonConsts.FUNDNO,PropertyConsts.FUNDNO);
			req.put(CommonConsts.STATE,state);
			logger.info("【自动申购预约商户信息修改接口】入参"+req);
			ResMessage ress = fundServiceRemote.updateFundMerInfo(req);
			logger.info("【自动申购预约商户信息修改接口】出参"+ress);
			if(!RetCode.SUCCESS.equals(ress.getRetCode())){
				logger.info("基金自动申购状态修改失败！");
				res.setRetCode(RetCode.FAIL);
				res.setRetMsg("基金自动申购状态修改失败！");
				return res;
			}
			logger.info("基金自动申购状态修改成功！");
			//判断自动申购-->开启？失败？
			//0关闭自动申购-->开启自动提现1
			if(state.equals("0")){
				String stateTX = "1";
				com.umfwechat.common.ResMessage resTx = this.txChange(request, response, stateTX ,merId);
				if(!resTx.getRetCode().equals(RetCode.SUCCESS)){
					logger.info("开启自动提现失败！");
					res.setRetCode(RetCode.FAIL);
					res.setRetMsg("基金自动申购状态修改成功！开启自动提现失败！");
					return res;
				}
				res.setRetCode(RetCode.SUCCESS);
				res.setRetMsg("基金自动申购状态修改成功！开启自动提现成功！");
				return res;
			}
			//1开启自动申购--》关闭自动提现0
			if(state.equals("1")){
				String stateTX = "0";
				com.umfwechat.common.ResMessage resTx = this.txChange(request, response, stateTX ,merId);
				if(!resTx.getRetCode().equals(RetCode.SUCCESS)){
					logger.info("关闭自动提现失败！");
					res.setRetCode(RetCode.FAIL);
					res.setRetMsg("基金自动申购状态修改成功！关闭自动提现失败！");
					return res;
				}
				res.setRetCode(RetCode.SUCCESS);
				res.setRetMsg("基金自动申购状态修改成功！关闭自动提现成功！");
				return res;
			}
		} catch (Exception e) {
			logger.info("基金自动申购状态修改失败！");
			res.setRetCode(RetCode.FAIL);
			res.setRetMsg("基金自动申购状态修改失败！");
		}
		return res;
	}
	
	/**
	 * 自动提现状态修改接口
	 * @param request
	 * @param response
	 * @param stateTX
	 * @return
	 */
	public com.umfwechat.common.ResMessage txChange(HttpServletRequest request ,HttpServletResponse response ,String stateTX ,String merId ){
		logger.info("自动提现状态修改接口");
		com.umfwechat.common.ResMessage resTx = new com.umfwechat.common.ResMessage();
		try {
			//获取自动提现 列表
			//1.设置查询条件
			com.umpay.sp.model.common.ReqMessage req = ReqMessageUtil.makeSpReq();
			req.put("merId", merId);
			req.put("state", "2");//2开通 
			logger.info("【查询商户自动提现规则列表接口】入参："+ req);
			com.umpay.sp.model.common.ResMessage res = entrustEdrawServiceRemote.queryEntrustEdrawList(req);
			logger.info("【查询商户自动提现规则列表接口】出参："+ res);
			if( !res.getRetCode().equals(RetCode.SUCCESS)){
				logger.info("查询自动提现规则列表失败！");
				resTx.setRetCode(RetCode.FAIL);
				resTx.setRetMsg("查询自动提现规则列表失败！");
				return resTx;
			}
			List<Map<String,Object>> ruleList = (List<Map<String, Object>>) res.getValue("resultList");
			//判断应该关闭、开启自动提现
			//关闭自动提现
			if(stateTX.equals("0")){
				logger.info("关闭自动提现");
				if (ruleList.size()>0) {
					for (int i=0;i<ruleList.size();i++){
						Map<String, Object> rule = ruleList.get(i);
						String edrawRuleId = StringUtil.trim(rule.get("edrawRuleId"));
//						String ruleState = StringUtil.trim(rule.get("state"));
							com.umpay.sp.model.common.ReqMessage cloReq = ReqMessageUtil.makeSpReq();
							//1.设置查询条件
							cloReq.put("merId",merId);
							cloReq.put("edrawRuleId",edrawRuleId);
							logger.info("【关闭自动提现】入参：" + cloReq);
							com.umpay.sp.model.common.ResMessage cloRes = entrustEdrawServiceRemote.stopEntrustEdrawConf(cloReq);
							logger.info("【关闭自动提现】出参：" + cloRes);
					}
				}
				logger.info("关闭自动提现成功！");
				resTx.setRetCode(RetCode.SUCCESS);
				resTx.setRetMsg("关闭自动提现成功！");
				return resTx;
			}
			//开启自动提现
			if(stateTX.equals("1")){
				logger.info("开启自动提现");
				if (ruleList.size()>0) {
					for (int i=0;i<ruleList.size();i++){
						Map<String, Object> rule = ruleList.get(i);
						String edrawRuleId = StringUtil.trim(rule.get("edrawRuleId"));
//						String ruleState = StringUtil.trim(rule.get("state"));
							com.umpay.sp.model.common.ReqMessage starReq = ReqMessageUtil.makeSpReq();
							//1.设置查询条件
							starReq.put("merId",merId);
							starReq.put("edrawRuleId",edrawRuleId);
							starReq.put("modUser","saas");
							logger.info("【开启自动提现】入参：" + starReq);
							com.umpay.sp.model.common.ResMessage starRes = entrustEdrawServiceRemote.startEntrustEdrawConf(starReq);
							logger.info("自动提现规则修改请求保存返回数据：" + starRes);
							logger.info("【开启自动提现】入参：" + starRes);

					}
				}
				logger.info("开启自动提现成功！");
				resTx.setRetCode(RetCode.SUCCESS);
				resTx.setRetMsg("开启自动提现成功！");
				return resTx;
			}
		} catch (Exception e) {
			logger.info("修改商户自动提现状态失败！");
			resTx.setRetCode(RetCode.FAIL);
			resTx.setRetMsg("修改商户自动提现状态失败！");
		}
		return resTx;
	}
	
	/**
	 * 基金自动申购状态开关接口
	 * @param request
	 * @param response
	 * @param state
	 * @return
	 */
	@RequestMapping(value="autoPurchase",method={RequestMethod.POST,RequestMethod.GET},produces="text/html;charset=UTF-8")
	@ResponseBody
	public String autoPurchase(HttpServletRequest request ,HttpServletResponse response ,String state){
		logger.info("基金自动申购状态修改接口开始！"+"state:" + state);
		//校验参数
		if(StringUtil.isEmpty(state)){
			logger.info("获取前台state值失败");
			return ResultJsonUtil.resultJson(RetCode.FAIL,MsgConsts.E00433077);
		}
		ResMessage res = this.autoPurchaseChange(request, response, state);
		if(!RetCode.SUCCESS.equals(res.getRetCode())){
			logger.info("基金自动申购状态修改失败");
			return ResultJsonUtil.resultJson(RetCode.FAIL, MsgConsts.E00433122);
		}
		logger.info("基金自动申购状态修改成功！");
		return ResultJsonUtil.resultJson(RetCode.SUCCESS, MsgConsts.I00433117);
	}

	/**
	 * 主商户注册操作【7】： 配置费率
	 */
	public Map<String,String> allocationRate(String productID,String merId){

		logger.info("【7】：添加产品费率信息，产品编号：" + productID);
		Map<String,String> map = new HashMap<String, String>();
		
		com.umpay.sp.model.common.ReqMessage re = ReqMessageUtil.makeSpReq();
		String rpid = re.getRpid();
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put(CommonConsts.RPID, rpid);
		params.put(CommonConsts.REQDATE, re.getReqDate());
		params.put(CommonConsts.REQTIME, re.getReqTime());
		params.put(CommonConsts.MERID,merId);
		params.put(CommonConsts.START_DATE, re.getReqDate());// 起始日期
		String url =UmfPropModel.INSTANCE.getPropValue(ConfigConsts.PAYMENT_ACC_FEE_URL);
		// 配置公共参数
		params.put(CommonConsts.PRODUCTID, productID);// 产品号
		params.put(CommonConsts.MINFEE,"0");//保底手续费
		params.put(CommonConsts.MAXFEE,"0");//封顶手续费
		params.put(CommonConsts.FEETYPE,"2");// 费率类型
		params.put(CommonConsts.FEEVALUE,"0");// 费率值
		params.put(CommonConsts.OPERUSER,"spapply");//操作人
		try {
			logger.info("【配置费率】httpPostForm2Xml请求数据：params"+params+ "访问路径url="+ url);	
			Map<String, Object> rescon = HttpUtil.httpPostForm2Xml(url, params);
			logger.info("【配置费率】httpPostForm2Xml返回结果：",rescon);
			if(null==rescon||StringUtil.isEmpty((String) rescon.get(CommonConsts.RETCODE))){
				logger.info("【配置费率】失败,返回值rescon="+rescon);
				map.put(CommonConsts.RETCODE,RetCode.FAIL);
				return map;
			}
			if(RetCode.SUCCESS.equals(StringUtil.trim(rescon.get(CommonConsts.RETCODE)))){
				logger.info("【配置费率】成功！");			
				map.put(CommonConsts.RETCODE,RetCode.SUCCESS);
			}else if(RetCode.ALLOCATION_EXIST.equals(StringUtil.trim(rescon.get(CommonConsts.RETCODE)))){
				logger.info("【配置费率】已存在，不需要配置！");		
				map.put(CommonConsts.RETCODE,RetCode.SUCCESS);
			}else if(RetCode.BORROW_EXIST.equals(StringUtil.trim(rescon.get(CommonConsts.RETCODE)))){
				logger.info("【配置费率】已存在，不需要配置！");		
				map.put(CommonConsts.RETCODE,RetCode.SUCCESS);
			}else{
				logger.info("【配置费率】失败,返回码"+rescon.get(CommonConsts.RETCODE));
				map.put(CommonConsts.RETCODE,RetCode.FAIL);
			}
		}catch (Exception e) {
			logger.error("调用配置费率接口异常"+e);
			map.put(CommonConsts.RETCODE,RetCode.FAIL);
			return map;
		}
		return map;
	}
}
